home *** CD-ROM | disk | FTP | other *** search
- /*$T matrix.c GC 1.137 08/09/02 17:47:18 */
-
- /*$6
- +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- */
-
- #include "zgl.h"
-
- /* */
-
- void gl_print_matrix(const float *m) {
- int i;
- /*~~*/
-
- for(i = 0; i < 4; i++) {
- fprintf(stderr, "%f %f %f %f\n", m[i], m[4 + i], m[8 + i], m[12 + i]);
- }
- }
-
- /* */
- static inline void gl_matrix_update(GLContext *c) {
- c->matrix_model_projection_updated = (c->matrix_mode <= 1);
- }
-
- /* */
- void glopMatrixMode(GLContext *c, GLParam *p) {
- int mode = p[1].i;
- switch(mode) {
- case GL_MODELVIEW: c->matrix_mode = 0; break;
- case GL_PROJECTION: c->matrix_mode = 1; break;
- case GL_TEXTURE: c->matrix_mode = 2; break;
- default: assert(0);
- }
- }
-
- /* */
- void glopLoadMatrix(GLContext *c, GLParam *p) {
- M4 *m;
- int i;
-
- GLParam *q;
-
- m = c->matrix_stack_ptr[c->matrix_mode];
- q = p + 1;
-
- for(i = 0; i < 4; i++) {
- m->m[0][i] = q[0].f;
- m->m[1][i] = q[1].f;
- m->m[2][i] = q[2].f;
- m->m[3][i] = q[3].f;
- q += 4;
- }
-
- gl_matrix_update(c);
- }
-
- /* */
- void glopLoadIdentity(GLContext *c, GLParam *p) {
- gl_M4_Id(c->matrix_stack_ptr[c->matrix_mode]);
-
- gl_matrix_update(c);
- }
-
- /* */
- void glopMultMatrix(GLContext *c, GLParam *p) {
- M4 m;
- int i;
-
- GLParam *q;
- q = p + 1;
-
- for(i = 0; i < 4; i++) {
- m.m[0][i] = q[0].f;
- m.m[1][i] = q[1].f;
- m.m[2][i] = q[2].f;
- m.m[3][i] = q[3].f;
- q += 4;
- }
-
- gl_M4_MulLeft(c->matrix_stack_ptr[c->matrix_mode], &m);
-
- gl_matrix_update(c);
- }
-
- /* */
- void glopPushMatrix(GLContext *c, GLParam *p) {
- int n = c->matrix_mode;
- M4 *m;
-
- assert((c->matrix_stack_ptr[n] - c->matrix_stack[n] + 1) < c->matrix_stack_depth_max[n]);
-
- m = ++c->matrix_stack_ptr[n];
-
- gl_M4_Move(&m[0], &m[-1]);
-
- gl_matrix_update(c);
- }
-
- /* */
- void glopPopMatrix(GLContext *c, GLParam *p) {
- int n = c->matrix_mode;
-
- assert(c->matrix_stack_ptr[n] > c->matrix_stack[n]);
- c->matrix_stack_ptr[n]--;
- gl_matrix_update(c);
- }
-
- /* */
- void glopRotate(GLContext *c, GLParam *p) {
- M4 m;
- float u[3];
- float angle;
- int dir_code;
-
- angle = p[1].f * M_PI / 180.0;
- u[0] = p[2].f;
- u[1] = p[3].f;
- u[2] = p[4].f;
-
- /* simple case detection */
- dir_code = ((u[0] != 0) << 2) | ((u[1] != 0) << 1) | (u[2] != 0);
-
- switch(dir_code) {
- case 0:
- gl_M4_Id(&m);
- break;
- case 4:
- if(u[0] < 0) {
- angle = -angle;
- }
-
- gl_M4_Rotate(&m, angle, 0);
- break;
- case 2:
- if(u[1] < 0) {
- angle = -angle;
- }
-
- gl_M4_Rotate(&m, angle, 1);
- break;
- case 1:
- if(u[2] < 0) {
- angle = -angle;
- }
-
- gl_M4_Rotate(&m, angle, 2);
- break;
- default: {
- float cost, sint;
-
- /* normalize vector */
- float len = u[0] * u[0] + u[1] * u[1] + u[2] * u[2];
- if(len == 0.0f) {
- return;
- }
-
- len = 1.0f / sqrt(len);
- u[0] *= len;
- u[1] *= len;
- u[2] *= len;
-
- /* store cos and sin values */
- cost = cos(angle);
- sint = sin(angle);
-
- /* fill in the values */
- m.m[3][0] = m.m[3][1] = m.m[3][2] = m.m[0][3] = m.m[1][3] = m.m[2][3] = 0.0f;
- m.m[3][3] = 1.0f;
-
- /* do the math */
- m.m[0][0] = u[0] * u[0] + cost * (1 - u[0] * u[0]);
- m.m[1][0] = u[0] * u[1] * (1 - cost) - u[2] * sint;
- m.m[2][0] = u[2] * u[0] * (1 - cost) + u[1] * sint;
- m.m[0][1] = u[0] * u[1] * (1 - cost) + u[2] * sint;
- m.m[1][1] = u[1] * u[1] + cost * (1 - u[1] * u[1]);
- m.m[2][1] = u[1] * u[2] * (1 - cost) - u[0] * sint;
- m.m[0][2] = u[2] * u[0] * (1 - cost) - u[1] * sint;
- m.m[1][2] = u[1] * u[2] * (1 - cost) + u[0] * sint;
- m.m[2][2] = u[2] * u[2] + cost * (1 - u[2] * u[2]);
- }
- }
-
- gl_M4_MulLeft(c->matrix_stack_ptr[c->matrix_mode], &m);
-
- gl_matrix_update(c);
- }
-
- /* */
- void glopScale(GLContext *c, GLParam *p) {
- float *m;
- float x = p[1].f, y = p[2].f, z = p[3].f;
-
- m = &c->matrix_stack_ptr[c->matrix_mode]->m[0][0];
-
- m[0] *= x;
- m[1] *= y;
- m[2] *= z;
- m[4] *= x;
- m[5] *= y;
- m[6] *= z;
- m[8] *= x;
- m[9] *= y;
- m[10] *= z;
- m[12] *= x;
- m[13] *= y;
- m[14] *= z;
- gl_matrix_update(c);
- }
-
- /* */
- void glopTranslate(GLContext *c, GLParam *p) {
- float *m;
- float x = p[1].f, y = p[2].f, z = p[3].f;
-
- m = &c->matrix_stack_ptr[c->matrix_mode]->m[0][0];
-
- m[3] = m[0] * x + m[1] * y + m[2] * z + m[3];
- m[7] = m[4] * x + m[5] * y + m[6] * z + m[7];
- m[11] = m[8] * x + m[9] * y + m[10] * z + m[11];
- m[15] = m[12] * x + m[13] * y + m[14] * z + m[15];
-
- gl_matrix_update(c);
- }
-
- /* */
- void glopFrustum(GLContext *c, GLParam *p) {
- float *r;
- M4 m;
- float left = p[1].f;
- float right = p[2].f;
- float bottom = p[3].f;
- float top = p[4].f;
- float near = p[5].f;
- float farp = p[6].f;
- float x, y, A, B, C, D;
-
- x = (2.0 * near) / (right - left);
- y = (2.0 * near) / (top - bottom);
- A = (right + left) / (right - left);
- B = (top + bottom) / (top - bottom);
- C = -(farp + near) / (farp - near);
- D = -(2.0 * farp * near) / (farp - near);
-
- r = &m.m[0][0];
- r[0] = x;
- r[1] = 0;
- r[2] = A;
- r[3] = 0;
- r[4] = 0;
- r[5] = y;
- r[6] = B;
- r[7] = 0;
- r[8] = 0;
- r[9] = 0;
- r[10] = C;
- r[11] = D;
- r[12] = 0;
- r[13] = 0;
- r[14] = -1;
- r[15] = 0;
-
- gl_M4_MulLeft(c->matrix_stack_ptr[c->matrix_mode], &m);
-
- gl_matrix_update(c);
- }
-